﻿using System;
using System.Data.Odbc;

namespace Centido.Core
{
    /// <summary>
    ///   A set of table restore operations.
    /// </summary>
    public static class TableRestoreOperations
    {
        /// <summary>
        ///   Restores a soft deleted row with the specified id.
        /// </summary>
        /// <remarks>
        /// <para>Restoring the row may result in restoring the rows that were referenced by the first one
        /// regardless of the value of CascadeDelete property in these references.</para>
        /// <para>The current user has to have the permission to change the schema in order to execute this function.</para>
        /// </remarks>
        ///<param name="table">The target table.</param>
        ///<param name = "rowId">The id of the specified row.</param>
        /// <exception cref="System.Data.Common.DbException">Thrown when the current user has no permission to change the schema.</exception>
        /// <exception cref="Centido.Core.DbOperationException">Thrown when there is no row with the specified id in the internal table.</exception>
        /// <example>
        ///   The following example shows the effect of cascade restore.
        /// <code>
        ///     using System;
        ///     using Centido.Core;
        /// 
        ///     class Sample
        ///     {
        ///         static void Main()
        ///         {
        ///             var domainConfig = new DomainConfiguration()
        ///             {
        ///                 DbConnectionString = @"Driver={SQL Server};Server=.\SQLEXPRESS;Database=MyDb;Uid=admin;Pwd=P@ssw0rd;",
        ///                 DbProviderName = "MSSQLSERVER"
        ///             };
        ///         
        ///             var domain = Domain.Build(domainConfig);
        ///             
        ///             domain.DeleteAll();
        ///             
        ///             //Creating a new table
        ///             var table = domain.AddTable("my_table");
        /// 
        ///             //Creating another table
        ///             var anotherTable = domain.AddTable("another_table");
        /// 
        ///             //Creating a reference
        ///             var refColumn = table.AddColumn("ref_col", ColumnType.Reference)
        ///                 as RefColumn;
        /// 
        ///             refColumn.AddTarget(anotherTable).HasCascadeDelete = true;             
        /// 
        ///             //Granting all necessary permissions
        ///             table.GrantAll();
        ///             anotherTable.GrantAll();
        ///
        ///             //Inserting rows
        ///             Console.WriteLine("Inserting rows");
        /// 
        ///             var anotherTableId = anotherTable.InsertRow();
        ///             var id = table.InsertRow(refColumn.Value(anotherTableId));
        ///             
        ///             Console.WriteLine("Table - Row count = {0}", table.RowCount);
        ///             Console.WriteLine("Another table - Row count = {0}", anotherTable.RowCount);
        ///             
        ///             //Deleting the row in another table
        ///             Console.WriteLine("Deleting the row in the second table");
        ///             
        ///             anotherTable.DeleteRow(anotherTableId);
        ///             
        ///             Console.WriteLine("Table - Row count = {0}", table.RowCount);
        ///             Console.WriteLine("Another table - Row count = {0}", anotherTable.RowCount);
        /// 
        ///             //Restoring the row in the first table
        ///             Console.WriteLine("Deleting the row in the first table");
        /// 
        ///             table.RestoreRow(id);
        /// 
        ///             Console.WriteLine("Table - Row count = {0}", table.RowCount);
        ///             Console.WriteLine("Another table - Row count = {0}", anotherTable.RowCount);
        ///         }
        ///     }
        /// </code>
        /// </example>
        public static void RestoreRow(this Table table, Guid rowId)
        {
            table.Domain.DbAccess.ExecuteNonQuery(
                cmd =>
                {
                    cmd.CommandText = string.Format("{{call {0}(?,?)}}",
                        table.Domain.GetObjectFullName(Db.Procedures.RestoreTableRow));

                    cmd.Parameters.Add(table.Domain.DbAccess.CreateParameter("a_table_id",
                        OdbcType.Binary, table.GetRawId()));
                    cmd.Parameters.Add(table.Domain.DbAccess.CreateParameter("a_row_id",
                        OdbcType.Binary, rowId.ToByteArray()));
                });
        }
    }
}
